#pragma once

#include "byteStream.hpp"
#include <cstdint>

enum class Dlt698DataType : uint8_t {
    DATA_TYPE_NULL,
    DATA_TYPE_ARRAY,
    DATA_TYPE_STRUCTURE,
    DATA_TYPE_BOOL,
    DATA_TYPE_BIT_STRING,
    DATA_TYPE_DOUBLE_LONG,
    DATA_TYPE_DOUBLE_LONG_UNSIGNED,
    DATA_TYPE_OCTET_STRING = 9,
    DATA_TYPE_VISIBLE_STRING,
    DATA_TYPE_UTF8_STRING = 12,
    DATA_TYPE_INTEGER = 15,
    DATA_TYPE_LONG,
    DATA_TYPE_UNSIGNED,
    DATA_TYPE_LONG_UNSIGNED,
    DATA_TYPE_LONG64 = 20,
    DATA_TYPE_LONG64_UNSIGNED,
    DATA_TYPE_ENUM,
    DATA_TYPE_FLOAT32,
    DATA_TYPE_FLOAT64,
    DATA_TYPE_DATE_TIME,
    DATA_TYPE_DATE,
    DATA_TYPE_TIME,
    DATE_TYPE_DATE_TIME_S,
    DATA_TYPE_OI = 80,
    DATA_TYPE_OAD,
    DATA_TYPE_ROAD,
    DATA_TYPE_OMD,
    DATA_TYPE_TI,
    DATA_TYPE_TSA,
    DATA_TYPE_MAC,
    DATA_TYPE_RN,
    DATA_TYPE_REGION,
    DATA_TYPE_SCALER_UNIT,
    DATA_TYPE_RSD,
    DATA_TYPE_CSD,
    DATA_TYPE_MS,
    DATA_TYPE_SID,
    DATA_TYPE_SID_MAC,
    DATA_TYPE_COMDCB,
    DATA_TYPE_RCSD,
};

inline bool operator==(uint8_t v, const Dlt698DataType &t) {
    return v == static_cast<uint8_t>(t);
}

inline bool operator==(const Dlt698DataType &t, uint8_t v) {
    return v == static_cast<uint8_t>(t);
}

class ServerApdu {
protected:
    ByteStream _stream;

    static inline const uint8_t responseSuccess = 0x01;
    static inline const uint8_t responseFailed = 0x00;

public:
    using DataValueType = std::vector<std::pair<uint8_t, ByteStream>>;

public:
    ServerApdu(const ByteStream &b)
        : _stream(b) {}

    virtual uint8_t apduType(void) const { return _stream[0]; }

    virtual ByteStream apdu(void) const { return _stream; }

    virtual bool isGood(void) const { return _stream.length() >= 8 && _stream[7] == responseSuccess; }

    virtual DataValueType value(void) const { return {}; }

    virtual ~ServerApdu() {}
};
